package org.practice.tags;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
 * 标签处理类
 * 在 JSP2.0以前，所有标签处理类都必须实现 Tag 接口，这样的标签称为传统标签.
 * JSP2.0 规范又定义了一种新的类型的标签，称为简单标签，其对应的处理类要实现 SimpleTag 接口
 * 自定义标记库：就是将标记库信息解析为java代码执行，并将执行的结果缓存在pageContext中
 * 页面通过EL表达式来取值，或者用ognl,或者使用pageContext.getAttribute();
 */
public class ForEachLoopTag extends SimpleTagSupport{
	private Object value;//表示迭代的集合
	private String id;//表示集合中的元素
	private String status;//表示集合中的元素的状态
	@Override
	public void doTag() throws JspException, IOException {
		PageContext pageContext = (PageContext)this.getJspContext();
		JspFragment jsp = getJspBody();//JspFragment表示标签体jsp片段对象
		Iterator<?> it = null;
		Status state = null;
		if (status != null) {
			state = new Status();
			pageContext.setAttribute(status,state);
		}
		if (value instanceof Collection<?>) {
			if (state!= null) {
				state.setLength(((Collection<?>) value).size());
			}
			it = ((Collection<?>) value).iterator();

		}else if (value instanceof Map<?,?>) {
			if (state != null) {
				state.setLength(((Map<?,?>)value).size());
			}
			it = ((Map<?,?>)value).entrySet().iterator();
		}else if (value instanceof Object[]) {
			if (state != null) {
				state.setLength(((Object[])value).length);
			}
			it = Arrays.asList((Object[])value).iterator();
		}else {
			throw new RuntimeException("无法迭代集合....");
		}
		int index = 0;
		while (it.hasNext()) {
			if (state != null) {
				state.setIndex(index++);
			}
			pageContext.setAttribute(id,it.next());
			//该方法用于执行 JspFragment对象所代表的 JSP代码片段,JspFragment对象处理完后写入到指定的输出流中
			jsp.invoke(pageContext.getOut());
		}
		pageContext.removeAttribute(id);
		pageContext.removeAttribute(status);
	}
	public Object getValue() {
		return value;
	}
	public void setValue(Object value) {
		this.value = value;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getStatus() {
		return status;
	}
	public void setStatus(String status) {
		this.status = status;
	}
	
	
}
